package com.kim.server.component;


import com.kim.server.handler.ServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.quarkus.logging.Log;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import java.util.concurrent.Executors;

@ApplicationScoped
@Slf4j
public class NettyServerConfig {

    @ConfigProperty(name = "netty.server.port")
    int serverPort;



    @PostConstruct
    public void start() {
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            executor.submit(() -> { // we use ES because otherwise the main thread will be blocked on line 50
                EventLoopGroup bossGroup = new NioEventLoopGroup(1);
                EventLoopGroup workerGroup = new NioEventLoopGroup();
                try {
                    ServerBootstrap b = new ServerBootstrap();
                    b.group(bossGroup, workerGroup) // Set boss & worker groups
                            .channel(NioServerSocketChannel.class)
                            .childHandler(new ChannelInitializer<SocketChannel>() {
                                @Override
                                public void initChannel(SocketChannel ch) throws Exception {
                                    ChannelPipeline p = ch.pipeline();
                                    p.addLast(new StringDecoder());
                                    p.addLast(new StringEncoder());
                                    p.addLast(new ServerHandler());
                                }
                            });
                    ChannelFuture f = b.bind(serverPort).sync();
                    log.info("Netty Server started.{} ","测试日志");
                    f.channel().closeFuture().sync();
                } catch (InterruptedException e) {
                    Log.info("Netty Server interrupted!!!");
                } finally {
                    bossGroup.shutdownGracefully();
                    workerGroup.shutdownGracefully();
                }
            });
        }
    }
}
